home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #2 / Monster Media No. 2 (Monster Media)(1994).ISO / prog_gen / cfilesys.zip / FILESYS.CPP < prev    next >
C/C++ Source or Header  |  1994-06-19  |  31KB  |  1,189 lines

  1.  
  2. //***************************************************************************
  3. //
  4. // Class:                    CFileSystem
  5. //
  6. // Purpose:                To encapsulate access to the file system.
  7. //
  8. // Copyright:            Copyright 1993, 1994 Scott P. Leslie, All Rights Reserved.
  9. //
  10. // Version:                Version 1.1 for MS Windows 3.1 and MSVC 1.0.
  11. //
  12. // Important:            Read the README.TXT file included with this distribution
  13. //                                before using this class.
  14. //
  15. // Shareware:            This class is ShareWare.  If you use it, you should register
  16. //                                it with the author.  If you do not register it after 14 days
  17. //                                of use, you must discontinue using it.
  18. //
  19. //                                Contact the author at ScotLeslie@aol.com for more info.
  20. //
  21. // Distribution:    You may distribute this class unmodified as long as all
  22. //                                accompanying documentation and notes are also distributed.
  23. //                                Object code generated from this class (or any derivation
  24. //                                of this class) can only be distributed by registered users.
  25. //
  26. // Disclaimer:        This class is provided as is with no implied or express
  27. //                                warranties.  You should test this class for your particular
  28. //                                use on non-critical data before using it in a production
  29. //                                system.
  30. //
  31. //***************************************************************************
  32.  
  33. //***************************************************************************
  34. //    Include Files
  35. //***************************************************************************
  36.  
  37. #include "stdafx.h"
  38.  
  39. #include "filesys.h"
  40.  
  41.  
  42. //***************************************************************************
  43. //
  44. // Name:        CFileSystem
  45. //
  46. // Purpose:    Constructor.
  47. //
  48. // Notes:        None.
  49. //
  50. //***************************************************************************
  51. CFileSystem::CFileSystem()
  52. {
  53.     MaxFileNameLength = 256;
  54. } // CFileSystem
  55.  
  56.  
  57. //***************************************************************************
  58. //
  59. // Name:        ~CFileSystem
  60. //
  61. // Purpose:    Destructor.
  62. //
  63. // Notes:        None.
  64. //
  65. //***************************************************************************
  66. CFileSystem::~CFileSystem()
  67. {
  68.     // No code.
  69. } // ~CFileSystem
  70.  
  71.  
  72. //***************************************************************************
  73. //
  74. // Name:        GetDirectoryEntry
  75. //
  76. // Purpose:    To return the next directory entry based on a wildcard, etc...
  77. //
  78. // Example:    CString *pFileName = fs.GetDirectoryEntry("*.txt", hidden);
  79. //
  80. // Notes:        None.
  81. //
  82. //***************************************************************************
  83. CString *
  84. CFileSystem::GetDirectoryEntry(const CString& Wildcard /* = "" */, const Attribute eFileAttrib /* = normal */)
  85. {
  86.     int nRetVal;
  87.  
  88.     // If they passed in a Wildcard, we want to lookup the first entry.
  89.     if (Wildcard != "")
  90.     {
  91.         nRetVal = _dos_findfirst((const char *) Wildcard, eFileAttrib, &m_FileInfo);
  92.     } // if
  93.     else
  94.     {
  95.         nRetVal = _dos_findnext(&m_FileInfo);
  96.     } // else
  97.  
  98.     if (nRetVal != 0)
  99.     {
  100.         // Error occurred, return NULL.
  101.         return NULL;
  102.     } // if
  103.  
  104.     // Create a string and copy the name to it.
  105.     CString *pString = new CString();
  106.     memcpy(pString->GetBufferSetLength(MaxFileNameLength), m_FileInfo.name, 13);
  107.     pString->ReleaseBuffer(-1);
  108.  
  109.     return pString;
  110. } // GetDirectoryEntry
  111.  
  112.  
  113. //***************************************************************************
  114. //
  115. // Name:        GetCurrentDirectory
  116. //
  117. // Purpose:    To get the current working directory.
  118. //
  119. // Example:    CString CurrentDir = fs.GetCurrentDirecory();
  120. //
  121. // Notes:        None
  122. //
  123. //***************************************************************************
  124. CString
  125. CFileSystem::GetCurrentDirectory()
  126. {
  127.     CString String;
  128.     char *pRetVal = _getcwd(String.GetBufferSetLength(MaxFileNameLength), MaxFileNameLength);
  129.     String.ReleaseBuffer(-1);
  130.  
  131.     // If an error occured, clean up and return NULL.
  132.     if (pRetVal == 0)
  133.     {
  134.         String = "";
  135.     } // if
  136.  
  137.     return String;
  138. } // GetCurrentDirectory
  139.  
  140.  
  141. //***************************************************************************
  142. //
  143. // Name:        ChangeDirectory
  144. //
  145. // Purpose:    To change the current working directory.
  146. //
  147. // Example:    BOOL bRetVal = fs.ChangeDirectory("c:\\foo\\bar");
  148. //
  149. // Notes:        None.
  150. //
  151. //***************************************************************************
  152. BOOL
  153. CFileSystem::ChangeDirectory(const CString& NewDirectory)
  154. {
  155.     int nRetVal = _chdir((const char *) NewDirectory);
  156.     if (nRetVal == -1)
  157.     {
  158.         return FALSE;
  159.     } // if
  160.  
  161.     return TRUE;
  162. } // ChangeDirectory
  163.  
  164.  
  165. //***************************************************************************
  166. //
  167. // Name:        MakeDirectory
  168. //
  169. // Purpose:    To make a directory.
  170. //
  171. // Example:    BOOL bRetVal = fs.MakeDirectory("c:\\foo\\bar");
  172. //
  173. // Notes:        None
  174. //
  175. //***************************************************************************
  176. BOOL
  177. CFileSystem::MakeDirectory(const CString& NewDirectory)
  178. {
  179. #ifdef _WINNT_
  180.     ASSERT(FALSE);    // Untested
  181.     return CreateDirectory(NewDirectory);
  182.  
  183. #else // _WINNT_
  184.  
  185.     int nRetVal = _mkdir((const char *) NewDirectory);
  186.     if (nRetVal == -1)
  187.     {
  188.         return FALSE;
  189.     } // if
  190.  
  191.     return TRUE;
  192.  
  193. #endif // _WINNT_
  194. } // MakeDirectory
  195.  
  196.  
  197. //***************************************************************************
  198. //
  199. // Name:        MakePath
  200. //
  201. // Purpose:    To make all the directories in a given path.  If any of the
  202. //                    directories exist, the creation continues with lower level
  203. //                    directories.
  204. //
  205. // Ret Val:    TRUE : No error.
  206. //                    FALSE : Unable to create path, or path already exists.
  207. //
  208. // Example:    BOOL bRetVal = fs.MakePath("c:\\foo\\bar\\what");
  209. //
  210. // Notes:        None
  211. //
  212. //***************************************************************************
  213. BOOL
  214. CFileSystem::MakePath(const CString& NewDirectory)
  215. {
  216.     CString NewDir = NewDirectory;    // Copy string for manipulation
  217.     CString    DirName;
  218.     BOOL        bRetVal = TRUE;
  219.  
  220.     // Make sure the directory name ends in a slash
  221.     if (NewDir[NewDir.GetLength() - 1] != '\\')
  222.     {
  223.         NewDir = NewDir + '\\';
  224.     } // if
  225.  
  226.     // Create each directory in the path
  227.     UINT    nIndex = 0;
  228.     BOOL    bDone = FALSE;
  229.     while (!bDone)
  230.     {
  231.         // Extract one directory
  232.         nIndex = NewDir.Find('\\');
  233.         if (nIndex != -1)
  234.         {
  235.             DirName = DirName + NewDir.Left(nIndex);
  236.             NewDir = NewDir.Right(NewDir.GetLength() - nIndex - 1);
  237.  
  238.             // The first time through, we might have a drive name
  239.             if (DirName.GetLength() >= 1  &&  DirName[DirName.GetLength() - 1] != ':')
  240.             {
  241.                 bRetVal = MakeDirectory(DirName);
  242.             } // if
  243.             DirName = DirName + '\\';
  244.         } // if
  245.         else
  246.         {
  247.             // We're finished
  248.             bDone = TRUE;
  249.         } // else
  250.     } // while
  251.  
  252.     // Return the last MakeDirectory() return value.
  253.     return bRetVal;
  254. } // MakePath
  255.  
  256.  
  257. //***************************************************************************
  258. //
  259. // Name:        DeleteDirectory
  260. //
  261. // Purpose:    To delete a directory.  Optionally, all lower level files
  262. //                    and directories can be deleted.
  263. //
  264. // Ret Val:    TRUE : Successfully deleted directory.
  265. //                    FALSE : Failed to delete directory.
  266. //
  267. // Example:    BOOL bRetVal = fs.DeleteDirectory("c:\\foo\\bar", TRUE);
  268. //
  269. // Notes:        If bDeleteFilesAndDirs == FALSE, directory must be empty or
  270. //                    an error will occur and FALSE will be returned.
  271. //
  272. //***************************************************************************
  273. BOOL
  274. CFileSystem::DeleteDirectory(const CString& Directory, const BOOL bDeleteFilesAndDirs /* = FALSE */)
  275. {
  276.     if (bDeleteFilesAndDirs)
  277.     {
  278.         CStringList *pSubDirs = GetSubdirList(Directory);
  279.         for (POSITION pos = pSubDirs->GetHeadPosition(); pos != NULL; )
  280.         {
  281.             CString DirName = pSubDirs->GetNext(pos);
  282.             DeleteDirectory(DirName, bDeleteFilesAndDirs);
  283.         } // for
  284.  
  285.         delete pSubDirs;
  286.         pSubDirs = NULL;
  287.  
  288.         DeleteFiles(AppendWildcard(Directory, "*.*"));
  289.     } // if
  290.  
  291.     int nRetVal = _rmdir((const char *) Directory);
  292.     if (nRetVal == -1)
  293.     {
  294.         return FALSE;
  295.     } // if
  296.  
  297.     return TRUE;
  298. } // DeleteDirectory
  299.  
  300.  
  301. //***************************************************************************
  302. //
  303. // Name:        GetDirectorySize
  304. //
  305. // Purpose:    To return the size (in bytes) of the files in the specified
  306. //                    directory.
  307. //
  308. // Example:    LONG lSize = fs.GetDirectorySize("c:\\foo\\bar", "*.*", TRUE);
  309. //
  310. // Notes:        If an error occurs in reading the status of a file, that
  311. //                    file is skipped and not counted as part of the size.
  312. //                    There is currently not way to find out if an error of this
  313. //                    kind occured.
  314. //
  315. //***************************************************************************
  316. LONG
  317. CFileSystem::GetDirectorySize(const CString& Directory /* = "" */, const CString& WildCard /* = "*.*" */, const BOOL bRecurseSubdirs /* = FALSE */)
  318. {
  319.     LONG lSize = 0;
  320.  
  321.     // Do all the subdirectories first...
  322.     if (bRecurseSubdirs)
  323.     {
  324.         CStringList *pSubDirs = GetSubdirList(Directory);
  325.         for (POSITION pos = pSubDirs->GetHeadPosition(); pos != NULL; )
  326.         {
  327.             CString DirName = pSubDirs->GetNext(pos);
  328.             lSize += GetDirectorySize(DirName, WildCard, bRecurseSubdirs);
  329.         } // for
  330.  
  331.         delete pSubDirs;
  332.         pSubDirs = NULL;
  333.     } // if
  334.  
  335.     // Find the sizes of all the files in the specified directory.
  336.     CStringList *pFileList = GetFileList(AppendWildcard(Directory, WildCard), allfiles);
  337.     for (POSITION pos = pFileList->GetHeadPosition(); pos != NULL; )
  338.     {
  339.         CFileStatus status;
  340.         CString FileName = pFileList->GetNext(pos);
  341.         if (CFile::GetStatus(FileName, status))
  342.         {
  343.             lSize += status.m_size;
  344.         } // if
  345.     } // for
  346.  
  347.     delete pFileList;
  348.     pFileList = NULL;
  349.     
  350.     return lSize;
  351. } // GetDirectorySize
  352.  
  353.  
  354. //***************************************************************************
  355. //
  356. // Name:        GetCurrentFileSystem
  357. //
  358. // Purpose:    To return a string containing the current file system name.
  359. //
  360. // Example:    CString FileSystem = fs.GetCurrentFileSystem();
  361. //
  362. // Notes:        None
  363. //
  364. //***************************************************************************
  365. CString
  366. CFileSystem::GetCurrentFileSystem()
  367. {
  368.     unsigned int    nDrive = 0;
  369.     char                    cDrive = 'A';
  370.  
  371.     _dos_getdrive(&nDrive);
  372.  
  373.     cDrive = (char) ('A' + nDrive - 1);
  374.     CString String = cDrive;
  375.     String += ":\\";
  376.  
  377.     return String;
  378. } // GetCurrentFileSystem
  379.  
  380.  
  381. //***************************************************************************
  382. //
  383. // Name:        ChangeFileSystem
  384. //
  385. // Purpose:    To change the current file system.
  386. //
  387. // Example:    BOOL bRetVal = fs.ChangeFileSystem('c');
  388. //
  389. // Notes:        Obsolete.  The version that takes a CString parameter
  390. //                    should be used instead.  This change was made in preparation
  391. //                    for the addition of Windows NT support.
  392. //
  393. //***************************************************************************
  394. BOOL
  395. CFileSystem::ChangeFileSystem(const char cFileSystem)
  396. {
  397.     unsigned int nNumDrives;        // ignored return value
  398.     unsigned int nNewDrive;
  399.  
  400.     nNewDrive = toupper(cFileSystem) - 'A' + 1;
  401.  
  402.     if (nNewDrive >= 0  &&  nNewDrive <= 26)
  403.     {
  404.         _dos_setdrive(nNewDrive, &nNumDrives);
  405.         return TRUE;
  406.     } // if
  407.  
  408.     return FALSE;
  409. } // ChangeFileSystem
  410.  
  411.  
  412. //***************************************************************************
  413. //
  414. // Name:        ChangeFileSystem
  415. //
  416. // Purpose:    To change the current file system.
  417. //
  418. // Example:    BOOL bRetVal = fs.ChangeFileSystem("c:\\");
  419. //
  420. // Notes:        Expects a filesystem name of the form "X:\".
  421. //
  422. //***************************************************************************
  423. BOOL
  424. CFileSystem::ChangeFileSystem(const CString& FileSystem)
  425. {
  426.     BOOL bRetVal = FALSE;
  427.  
  428.     if (FileSystem.GetLength() > 0)
  429.     {
  430.         char cFileSystem = FileSystem[0];
  431.         bRetVal = ChangeFileSystem(cFileSystem);
  432.     } // if
  433.  
  434.     return bRetVal;
  435. } // ChangeFileSystem
  436.  
  437.  
  438. //***************************************************************************
  439. //
  440. // Name:        GetFileSystemList
  441. //
  442. // Purpose:    To return a list of available file systems (ie. drives).
  443. //
  444. // Example:    CStringList *pFSList = fs.GetFileSystemList();
  445. //
  446. // Notes:        None
  447. //
  448. //***************************************************************************
  449. CStringList    *
  450. CFileSystem::GetFileSystemList()
  451. {
  452.     CStringList *pStringList = new CStringList();
  453.  
  454.     for (int nDriveNum = 0; nDriveNum < 26; nDriveNum++)
  455.     {
  456.         if (GetDriveType(nDriveNum) != 0)
  457.         {
  458.             CString DriveName = (char)('A' + nDriveNum);
  459.             DriveName = DriveName + ":\\";
  460.             pStringList->AddTail((const char *)DriveName);
  461.         } // if
  462.     } // for
  463.  
  464.     return pStringList;
  465. } // GetFileSystemList
  466.  
  467.  
  468. //***************************************************************************
  469. //
  470. // Name:        GetVolumeLabel
  471. //
  472. // Purpose:    To get the volume label for a filesystem.
  473. //
  474. // Example:    CString VolumeLabel = fs.GetVolumneLabel("c:\\");
  475. //
  476. // Notes:        None
  477. //
  478. //***************************************************************************
  479. CString
  480. CFileSystem::GetVolumeLabel(const CString& FileSystem)
  481. {
  482.     CString VolumeLabel = "";
  483.     CString *pVolLabel = GetDirectoryEntry(AppendWildcard(FileSystem, "*.*"), volume);
  484.     if (pVolLabel != NULL)
  485.     {
  486.         VolumeLabel = *pVolLabel;
  487.  
  488.         delete pVolLabel;
  489.         pVolLabel = NULL;
  490.     } // if
  491.  
  492.     return VolumeLabel;
  493. } // GetVolumeLabel
  494.  
  495.  
  496. //***************************************************************************
  497. //
  498. // Name:        GetFileSystemType
  499. //
  500. // Purpose:    To get the type (removable, network, etc...) of the specified
  501. //                    filesystem.
  502. //
  503. // Ret Val:    0 = Error.
  504. //                    DRIVE_REMOVABLE : Removable Disk (ie. floppy)
  505. //                    DRIVE_FIXED : Non-Removable Disk (ie. hard drive)
  506. //                    DRIVE_REMOTE : Network Disk (ie. NFS mounted, Netware volume)
  507. //
  508. // Example:    LONG lType = fs.GetFileSystemType("c:\\");
  509. //                    ASSERT(lType == DRIVE_FIXED);
  510. //
  511. // Notes:        None
  512. //
  513. //***************************************************************************
  514. LONG
  515. CFileSystem::GetFileSystemType(const CString& FileSystem)
  516. {
  517.     LONG lType = DRIVE_UNDETERMINED;
  518.  
  519.     if (FileSystem.GetLength() > 0)
  520.     {
  521.         char cFileSystem = (char) toupper(FileSystem[0]);
  522.  
  523.         int nDriveNum = toupper(cFileSystem) - 'A';
  524.     
  525.         if (nDriveNum >= 0  &&  nDriveNum <= 26)
  526.         {
  527.             lType = GetDriveType(nDriveNum);
  528.         } // if
  529.     } // if
  530.  
  531.     return lType;
  532. } // GetFileSystemType
  533.  
  534.  
  535. //***************************************************************************
  536. //
  537. // Name:        RenameFile
  538. //
  539. // Purpose:    To rename a file.
  540. //
  541. // Example:    BOOL bRetVal = fs.RenameFile("c:\\foo.txt", "c:\\bar.doc");
  542. //
  543. // Notes:        None
  544. //
  545. //***************************************************************************
  546. BOOL
  547. CFileSystem::RenameFile(const CString& OldFileName, const CString& NewFileName)
  548. {
  549.     TRY
  550.     {
  551.         CFile::Rename((const char *) OldFileName, (const char *) NewFileName);
  552.     } // TRY
  553.     CATCH(CFileException, Exception)
  554.     {
  555.         return FALSE;
  556.     } // CATCH
  557.     END_CATCH
  558.  
  559.     return TRUE;
  560. } // RenameFile
  561.  
  562.  
  563. //***************************************************************************
  564. //
  565. // Name:        DeleteFiles
  566. //
  567. // Purpose:    To delete a set of files based on a wildcard file specification.
  568. //
  569. // Example:    BOOL bRetVal = fs.DeleteFiles("c:\\foo\\bar\\*.txt");
  570. //
  571. // Notes:        Only normal files (not hidden or system) files can be deleted
  572. //                    with this function.
  573. //
  574. //***************************************************************************
  575. BOOL
  576. CFileSystem::DeleteFiles(const CString& FileSpec)
  577. {
  578.     BOOL bRetVal = TRUE;
  579.     CStringList *pDir = GetDirectory(FileSpec, normal);
  580.  
  581.     for (POSITION pos = pDir->GetHeadPosition(); pos != NULL; )
  582.     {
  583.         CString FileName = pDir->GetNext(pos);
  584.         if (DeleteFile(FileName) == FALSE)
  585.         {
  586.             bRetVal = FALSE;
  587.         } // if
  588.     } // for
  589.  
  590.     // Clean up.
  591.     delete pDir;
  592.     pDir = NULL;
  593.  
  594.     return bRetVal;
  595. } // DeleteFiles
  596.  
  597.  
  598. //***************************************************************************
  599. //
  600. // Name:        DeleteFile
  601. //
  602. // Purpose:    To delete a file.
  603. //
  604. // Example:
  605. //                    BOOL bRetVal = fs.DeleteFile("c:\foo.txt");
  606. //
  607. // Notes:        None
  608. //
  609. //***************************************************************************
  610. BOOL
  611. CFileSystem::DeleteFile(const CString& FileName)
  612. {
  613.     TRY
  614.     {
  615.         CFile::Remove((const char *) FileName);
  616.     } // TRY
  617.     CATCH(CFileException, Exception)
  618.     {
  619.         return FALSE;
  620.     } // CATCH
  621.     END_CATCH
  622.  
  623.     return TRUE;
  624. } // DeleteFile
  625.  
  626.  
  627. //***************************************************************************
  628. //
  629. // Name:        CloseFile
  630. //
  631. // Purpose:    To close a file.
  632. //
  633. // Notes:        None
  634. //
  635. //***************************************************************************
  636. BOOL
  637. CFileSystem::CloseFile(CFile *pFile) const
  638. {
  639.     BOOL bRetVal = TRUE;
  640.  
  641.     TRY
  642.     {
  643.         pFile->Close();
  644.     } // TRY
  645.     CATCH(CFileException, e)
  646.     {
  647.         bRetVal = FALSE;
  648.     } // CATCH
  649.     END_CATCH
  650.  
  651.     return bRetVal;
  652. } // CloseFile
  653.  
  654.  
  655. //***************************************************************************
  656. //
  657. // Name:        CopyFile
  658. //
  659. // Purpose:    To copy a file.
  660. //
  661. // Ret Val:    TRUE : File was copied successfully.
  662. //                    FALSE : Error occured.
  663. //
  664. // Example:    BOOL bRetVal = fs.CopyFile("foo.txt", "a:\\bar.txt", 20480);
  665. //
  666. // Notes:        If the destination file exists, an error occurs.
  667. //
  668. //***************************************************************************
  669. BOOL
  670. CFileSystem::CopyFile(const CString& SourceFileName, const CString& DestFileName, const unsigned long lBuffSize /* = 10240 */)
  671. {
  672.     BOOL        bRetVal    = TRUE;
  673.     char *    pBuff        = new char[lBuffSize];
  674.     CFile Source;
  675.     CFile Dest;
  676.  
  677.     // Check for exitance of the destination file.
  678.     CFileStatus destStatus;
  679.     if ((CFile::GetStatus(DestFileName, destStatus)))
  680.     {
  681.         delete [] pBuff;
  682.         pBuff = NULL;
  683.  
  684.         return FALSE;
  685.     } // if
  686.  
  687.     // Open the files, creating the destination.
  688.     if (Source.Open((const char *) SourceFileName, CFile::modeRead))
  689.     {
  690.         if (Dest.Open((const char *) DestFileName, CFile::modeCreate | CFile::modeWrite))
  691.         {
  692.             DWORD    dwLength = Source.GetLength();
  693.         
  694.             // Copy the data in the file.
  695.             while (dwLength > 0)
  696.             {
  697.                 UINT nRead = Source.Read(pBuff, (UINT) lBuffSize);
  698.                 if (nRead)
  699.                 {
  700.                     Dest.Write(pBuff, nRead);
  701.                 } // if
  702.             
  703.                 dwLength -= nRead;
  704.             } // while
  705.         
  706.             CloseFile(&Source);
  707.             CloseFile(&Dest);
  708.         } // if
  709.         else
  710.         {
  711.             CloseFile(&Source);
  712.  
  713.             bRetVal = FALSE;
  714.         } // else
  715.     } // if
  716.     else
  717.     {
  718.         bRetVal = FALSE;
  719.     } // else
  720.  
  721.     delete [] pBuff;
  722.     pBuff = NULL;
  723.  
  724.     return bRetVal;
  725. } // CopyFile
  726.  
  727.  
  728. //***************************************************************************
  729. //
  730. // Name:        CopyFiles
  731. //
  732. // Purpose:    To copy a set of files based on a wildcard file specification.
  733. //
  734. // Example:    BOOL bRetVal = fs.CopyFiles("c:\\foo\\bar\\*.txt", "c:\\foo2");
  735. //
  736. // Notes:        Only normal files (not hidden or system) files can be copied
  737. //                    with this function.
  738. //
  739. //***************************************************************************
  740. BOOL
  741. CFileSystem::CopyFiles(const CString& FileSpec, const CString& DestPath)
  742. {
  743.     BOOL bRetVal = TRUE;
  744.     CStringList *pDir = GetDirectory(FileSpec, normal);
  745.  
  746.     for (POSITION pos = pDir->GetHeadPosition(); pos != NULL; )
  747.     {
  748.         CString FileName = pDir->GetNext(pos);
  749.         CString DestFileName = AppendWildcard(DestPath, GetFileName(FileName));
  750.  
  751.         if (CopyFile(FileName, DestFileName) == FALSE)
  752.         {
  753.             bRetVal = FALSE;
  754.         } // if
  755.     } // for
  756.  
  757.     // Clean up.
  758.     delete pDir;
  759.     pDir = NULL;
  760.  
  761.     return bRetVal;
  762. } // CopyFiles
  763.  
  764.  
  765. //***************************************************************************
  766. //
  767. // Name:        CompareFiles
  768. //
  769. // Purpose:    To compare the contents of two files to see if they are the
  770. //                    same.
  771. //
  772. // Ret Val:    TRUE, if the files are the same.
  773. //                    FALSE, if the files are different, or an error occurs.
  774. //
  775. // Example:    BOOL bRetVal = fs.CompareFiles("foo.txt", "bar.txt", 20480);
  776. //
  777. // Notes:        None
  778. //
  779. //***************************************************************************
  780. BOOL
  781. CFileSystem::CompareFiles(const CString& FileName1, const CString& FileName2, const unsigned long lBuffSize /* = 10240 */)
  782. {
  783.     BOOL        bRetVal    = TRUE;
  784.     char *    pBuff1    = new char[lBuffSize];
  785.     char *    pBuff2    = new char[lBuffSize];
  786.     CFile        File1;
  787.     CFile        File2;
  788.  
  789.     // Make sure we allocated the buffers
  790.     if (!pBuff1  ||  !pBuff2)
  791.     {
  792.         if (pBuff1)
  793.         {
  794.             delete [] pBuff1;
  795.         } // if
  796.  
  797.         if (pBuff2)
  798.         {
  799.             delete [] pBuff2;
  800.         } // if
  801.  
  802.         return FALSE;
  803.     } // if
  804.  
  805.     // Open the files.
  806.     if (File1.Open((const char *) FileName1, CFile::modeRead))
  807.     {
  808.         if (File2.Open((const char *) FileName2, CFile::modeRead))
  809.         {
  810.             DWORD    dwLength1 = File1.GetLength();
  811.             DWORD    dwLength2 = File2.GetLength();
  812.             if (dwLength1 != dwLength2)
  813.             {
  814.                 bRetVal = FALSE;
  815.             } // if
  816.  
  817.             // Read the data in the file.
  818.             while (bRetVal == TRUE  &&  dwLength1 > 0)
  819.             {
  820.                 UINT nRead1 = File1.Read(pBuff1, (UINT) lBuffSize);
  821.                 UINT nRead2 = File2.Read(pBuff2, (UINT) lBuffSize);
  822.  
  823.                 if (nRead1 != nRead2)
  824.                 {
  825.                     bRetVal = FALSE;
  826.                     break;                            // break out of the while loop
  827.                 } // if
  828.  
  829.                 if (memcmp(pBuff1, pBuff2, nRead1) != 0)
  830.                 {
  831.                     bRetVal = FALSE;
  832.                 } // if
  833.             
  834.                 dwLength1 -= nRead2;
  835.             } // while
  836.  
  837.             CloseFile(&File1);
  838.             CloseFile(&File2);
  839.         } // if
  840.         else
  841.         {
  842.             CloseFile(&File1);
  843.  
  844.             bRetVal = FALSE;
  845.         } // else
  846.     } // if
  847.     else
  848.     {
  849.         bRetVal = FALSE;
  850.     } // else
  851.  
  852.     delete [] pBuff1;
  853.     delete [] pBuff2;
  854.  
  855.     return bRetVal;
  856. } // CompareFiles
  857.  
  858.  
  859. //***************************************************************************
  860. //
  861. // Name:        GetFileName
  862. //
  863. // Purpose:    Extract a file name from a path.
  864. //
  865. // Example:    CString FileName = fs.GetFileName("c:\\foo\\bar\\what.txt");
  866. //                    ASSERT(FileName == "what.txt");
  867. //
  868. // Notes:        None
  869. //
  870. //***************************************************************************
  871. CString
  872. CFileSystem::GetFileName(const CString& PathAndFileName)
  873. {
  874.     CString FileName = PathAndFileName;    // Copy to make modifications.
  875.  
  876.     // Find the last "\" in the string and return everything after it.
  877.     int nIndex = FileName.Find('\\');
  878.     while(nIndex != -1)
  879.     {
  880.         FileName = FileName.Right(FileName.GetLength() - nIndex - 1);
  881.  
  882.         nIndex = FileName.Find('\\');
  883.     } // while
  884.  
  885.     return FileName;
  886. } // GetFileName
  887.  
  888.  
  889. //***************************************************************************
  890. //
  891. // Name:        GetPath
  892. //
  893. // Purpose:    To return the directory from a path.
  894. //
  895. // Example:    CString Path = fs.GetPath("c:\\foo\\bar\\what.txt");
  896. //                    ASSERT(Path == "c:\\foo\\bar");
  897. //
  898. // Notes:        None
  899. //
  900. //***************************************************************************
  901. CString
  902. CFileSystem::GetPath(const CString& PathAndFileName)
  903. {
  904.     CString FileName = PathAndFileName; // Copy to modify;
  905.     CString    Path = "";
  906.  
  907.     // Find the last "\" in the string and return everything up to and including it.
  908.     int nIndex = FileName.Find('\\');
  909.     while(nIndex != -1)
  910.     {
  911.         Path = Path + FileName.Left(nIndex + 1);
  912.         FileName = FileName.Right(FileName.GetLength() - nIndex - 1);
  913.  
  914.         nIndex = FileName.Find('\\');
  915.     } // while
  916.  
  917.     return Path;
  918. } // GetPath
  919.  
  920.  
  921. //***************************************************************************
  922. //
  923. // Name:        GetDirectory
  924. //
  925. // Purpose:    To return a list of files based on a search string, etc...
  926. //
  927. // Example:    CStringList *pDir = fs.GetDirectory("*.txt", normal, TRUE);
  928. //                    (void) fs.GetDirectory("*.doc", normal, TRUE, pDir);
  929. //
  930. // Notes:        The filenames include the path.
  931. //
  932. //***************************************************************************
  933. CStringList    *
  934. CFileSystem::GetDirectory(const CString& SearchString, const Attribute eFileAttrib, const BOOL bRecurseSubDirs /* = FALSE */, CStringList *pStringList /* = NULL */)
  935. {
  936.     // If they don't pass in a list, create one.
  937.     if (pStringList == NULL)
  938.     {
  939.         pStringList = new CStringList();
  940.     } // if
  941.  
  942.     // Read the file list.
  943.     CStringList *pFileList = GetFileList(SearchString, eFileAttrib);
  944.     pStringList->AddTail(pFileList);
  945.     delete pFileList;
  946.     pFileList = NULL;
  947.  
  948.     if (bRecurseSubDirs)
  949.     {
  950.         CString                CurDir = GetPath(SearchString);
  951.         CStringList *    pDirList = GetSubdirList(CurDir);
  952.  
  953.         // Go through the directories we just got and recurse through them too.
  954.         for (POSITION pos=pDirList->GetHeadPosition(); pos != 0; )
  955.         {
  956.             CString String = pDirList->GetNext(pos);
  957.  
  958.             // Get file name part of search path
  959.             CString    SearchSpec = GetFileName(SearchString);
  960.  
  961.             // Do the recursion.
  962.             GetDirectory(String + "\\" + SearchSpec, eFileAttrib, bRecurseSubDirs, pStringList);
  963.         } // for
  964.  
  965.         delete pDirList;
  966.         pDirList = NULL;
  967.     } // if
  968.  
  969.     return pStringList;
  970. } // GetDirectory
  971.  
  972.  
  973. //***************************************************************************
  974. //
  975. // Name:        GetSubdirList
  976. //
  977. // Purpose:    To return a list of subdirectories of another directory.
  978. //
  979. // Example:
  980. //                    CStringList *pDirs = fs.GetSubdirList("c:\\foo", FALSE);
  981. //
  982. // Notes:        None
  983. //
  984. //***************************************************************************
  985. CStringList *
  986. CFileSystem::GetSubdirList(const CString& SearchDir, const BOOL bPathInName /* = TRUE */)
  987. {
  988.     // Read the directory list
  989.     CStringList *    pDirList = new CStringList();
  990.  
  991.     CString SearchPath = AppendWildcard(SearchDir, "*.*");
  992.     CString *    pString = GetDirectoryEntry(SearchPath, directory);
  993.     while (pString != NULL)
  994.     {
  995.         CString    String;
  996.         CString    FullPath;
  997.         CString    CurDir = GetPath(SearchPath);
  998.         sprintf(FullPath.GetBufferSetLength(1024), "%s%s", (const char *)CurDir, (const char *)(*pString));
  999.         FullPath.ReleaseBuffer(-1);
  1000.         if (bPathInName)
  1001.         {
  1002.             sprintf(String.GetBufferSetLength(1024), "%s%s", (const char *)CurDir, (const char *)(*pString));
  1003.             String.ReleaseBuffer(-1);
  1004.         } // if
  1005.         else
  1006.         {
  1007.             sprintf(String.GetBufferSetLength(1024), "%s", (const char *)(*pString));
  1008.             String.ReleaseBuffer(-1);
  1009.         } // else
  1010.  
  1011.         // If it's not one of the special directories.
  1012.         if (*pString != "."  &&  *pString != "..")
  1013.         {
  1014.             // Get the file type and make sure it's a directory before we add it to the list.
  1015.             CFileStatus FileStatus;
  1016.             CFile::GetStatus((const char *) FullPath, FileStatus);
  1017.             if (FileStatus.m_attribute == directory)
  1018.             {
  1019.                 pDirList->AddTail((const char *) String);
  1020.             } // if
  1021.         } // if
  1022.  
  1023.         // Delete the string we got back from GetDirectoryEntry
  1024.         delete pString;
  1025.         pString = NULL;
  1026.     
  1027.         pString = GetDirectoryEntry();
  1028.     } // while
  1029.  
  1030.     return pDirList;
  1031. } // GetSubdirList
  1032.  
  1033.  
  1034. //***************************************************************************
  1035. //
  1036. // Name:        GetFileList
  1037. //
  1038. // Purpose:    Return a list of files given a search path and attribute.
  1039. //
  1040. // Notes:        This only searches the specified directory.
  1041. //                    Use GetDirectory() to recurse subdirectories.
  1042. //                    The filenames include the path.
  1043. //
  1044. // Example:
  1045. //                    CStringList *pList = GetFileList("c:\\foo\\bar\\*.cpp", normal);
  1046. //
  1047. //***************************************************************************
  1048. CStringList *
  1049. CFileSystem::GetFileList(const CString& SearchString, const Attribute eFileAttrib)
  1050. {
  1051.     CStringList *pDirList = new CStringList();
  1052.  
  1053.     // Read the file list
  1054.     CString        CurDir = GetPath(SearchString);
  1055.     CString *    pString = GetDirectoryEntry(SearchString, eFileAttrib);
  1056.     CString    String;
  1057.     while (pString != NULL)
  1058.     {
  1059.         sprintf(String.GetBufferSetLength(1024), "%s%s", (const char *)CurDir, (const char *)(*pString));
  1060.         String.ReleaseBuffer(-1);
  1061.         pDirList->AddTail((const char *) String);
  1062.  
  1063.         // Delete the string we got back from GetDirectoryEntry
  1064.         delete pString;
  1065.         pString = NULL;
  1066.  
  1067.         pString = GetDirectoryEntry();
  1068.     } // while
  1069.  
  1070.     return pDirList;
  1071. } // GetFileList
  1072.  
  1073.  
  1074. //***************************************************************************
  1075. //
  1076. // Name:        Sort
  1077. //
  1078. // Purpose:    To sort the give string list.
  1079. //
  1080. // Exmaple:
  1081. //                    fs.Sort(pDirList);
  1082. //
  1083. // Notes:        None
  1084. //
  1085. //***************************************************************************
  1086. void
  1087. CFileSystem::Sort(CStringList *pStringList)
  1088. {
  1089.     int nListSize = pStringList->GetCount();
  1090.     for (int i = 0; i < nListSize-1; i++)
  1091.     {
  1092.         CString String1 = pStringList->GetAt(pStringList->FindIndex(i));
  1093.         for (int j = i+1; j < nListSize; j++)
  1094.         {
  1095.             CString String2 = pStringList->GetAt(pStringList->FindIndex(j));
  1096.             if (String1 > String2)
  1097.             {
  1098.                 // Swap.
  1099.                 pStringList->SetAt(pStringList->FindIndex(i), String2);
  1100.                 pStringList->SetAt(pStringList->FindIndex(j), String1);
  1101.  
  1102.                 String1 = String2;
  1103.             } // if
  1104.         } // for
  1105.     } // for
  1106. } // Sort
  1107.  
  1108.  
  1109. //***************************************************************************
  1110. //
  1111. // Name:        LoadListBox
  1112. //
  1113. // Purpose:    To load a list box with the given string list.
  1114. //
  1115. // Exmaple:
  1116. //                    fs.LoadListBox(pListBox, pDirList);
  1117. //
  1118. // Notes:        None
  1119. //
  1120. //***************************************************************************
  1121. void
  1122. CFileSystem::LoadListBox(CListBox *pListBox, const CStringList * pStringList)
  1123. {
  1124.     for (POSITION pos=pStringList->GetHeadPosition(); pos != 0; )
  1125.     {
  1126.         CString String = pStringList->GetNext(pos);
  1127.         pListBox->AddString(String);
  1128.     } // for
  1129. } // LoadListBox
  1130.  
  1131.  
  1132. //***************************************************************************
  1133. //
  1134. // Name:        LoadComboBox
  1135. //
  1136. // Purpose:    To load a combo box with the given string list.
  1137. //
  1138. // Example:
  1139. //                    fs.LoadListBox(pComboBox1, pDirList);
  1140. //
  1141. // Notes:        None
  1142. //
  1143. //***************************************************************************
  1144. void
  1145. CFileSystem::LoadComboBox(CComboBox *pComboBox, const CStringList * pStringList)
  1146. {
  1147.     for (POSITION pos=pStringList->GetHeadPosition(); pos != 0; )
  1148.     {
  1149.         CString String = pStringList->GetNext(pos);
  1150.         pComboBox->AddString(String);
  1151.     } // for
  1152. } // LoadComboBox
  1153.  
  1154.  
  1155. //***************************************************************************
  1156. //
  1157. // Name:        AppendWildcard
  1158. //
  1159. // Purpose:    To append a wildcard to a path.  It takes into account
  1160. //                    whether the path has a backslash at the end.
  1161. //
  1162. // Example:
  1163. //                    CString foo = fs.AppendWildcard("c:\\foo\\bar", "*.txt");
  1164. //                    ASSERT(foo == "c:\\foo\\bar\\*.txt");
  1165. //                    CString foo = fs.AppendWildcard("c:\\foo\\bar\\", "*.txt");
  1166. //                    ASSERT(foo == "c:\\foo\\bar\\*.txt");
  1167. //
  1168. // Notes:        If the path is the empty string, the Wildcard is returned.
  1169. //
  1170. //***************************************************************************
  1171. CString
  1172. CFileSystem::AppendWildcard(const CString& Path, const CString& Wildcard)
  1173. {
  1174.     long lLength = Path.GetLength();
  1175.     CString RetVal;
  1176.  
  1177.     if (lLength == 0  ||  Path.GetAt((int)(lLength - 1)) == '\\')
  1178.     {
  1179.         RetVal = Path + Wildcard;
  1180.     } // if
  1181.     else
  1182.     {
  1183.         RetVal = Path + "\\" + Wildcard;
  1184.     } // else
  1185.  
  1186.     return RetVal;
  1187. } // AppendWildcard
  1188.  
  1189.